package com.qingzhuge.manager.controller.base;

import com.qingzhuge.controller.BasePkLongController;
import com.qingzhuge.dto.request.BaseRequestPkLongDto;
import com.qingzhuge.dto.response.BaseResponsePkLongDto;
import com.qingzhuge.entity.BasePkLongEntity;
import com.qingzhuge.manager.entity.SysUser;
import com.qingzhuge.service.IBasePkLongService;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;

/**
 * @author : zero.xiao
 * @description : Controller公共组件
 * @date :2018/6/8 0008 下午 14:47
 * @modified :
 */
public abstract class BaseUidPkLongController<
        T extends BasePkLongEntity,
        S extends IBasePkLongService<T>,
        ReqD extends BaseRequestPkLongDto,
        ResD extends BaseResponsePkLongDto> extends BasePkLongController<T, S, ReqD, ResD> {

    /**
     * 获取当前用户
     */
    @Override
    protected SysUser getCurrUser() {

        // 获取安全上下文对象，就是那个保存在 ThreadLocal 里面的安全上下文对象
        // 总是不为null(如果不存在，则创建一个authentication属性为null的empty安全上下文对象)
        SecurityContext securityContext = SecurityContextHolder.getContext();

        // 获取当前认证了的 principal(当事人),或者 request token (令牌)
        // 如果没有认证，会是 null,该例子是认证之后的情况
        Authentication authentication = securityContext.getAuthentication();
        if (null != authentication) {
            // 获取当事人信息对象，返回结果是 Object 类型，但实际上可以是应用程序自定义的带有更多应用相关信息的某个类型。
            // 很多情况下，该对象是 Spring Security 核心接口 UserDetails 的一个实现类，你可以把 UserDetails 想像
            // 成我们数据库中保存的一个用户信息到 SecurityContextHolder 中 Spring Security 需要的用户信息格式的
            // 一个适配器。
            Object principal = authentication.getPrincipal();
            if (principal instanceof SysUser) {
                return (SysUser) principal;
            }
        }
        return null;
    }

    /**
     * 获取当前用户Id
     */
    @Override
    protected Long getUserId() {
        // 获取安全上下文对象，就是那个保存在 ThreadLocal 里面的安全上下文对象
        // 总是不为null(如果不存在，则创建一个authentication属性为null的empty安全上下文对象)
        SecurityContext securityContext = SecurityContextHolder.getContext();

        // 获取当前认证了的 principal(当事人),或者 request token (令牌)
        // 如果没有认证，会是 null,该例子是认证之后的情况
        Authentication authentication = securityContext.getAuthentication();
        if (null != authentication) {
            // 获取当事人信息对象，返回结果是 Object 类型，但实际上可以是应用程序自定义的带有更多应用相关信息的某个类型。
            // 很多情况下，该对象是 Spring Security 核心接口 UserDetails 的一个实现类，你可以把 UserDetails 想像
            // 成我们数据库中保存的一个用户信息到 SecurityContextHolder 中 Spring Security 需要的用户信息格式的
            // 一个适配器。
            Object principal = authentication.getPrincipal();
            if (principal instanceof SysUser) {
                return ((SysUser) principal).getId();
            }
        }
        return null;
    }

}
